/********************************************************************
* @Copyright: Metanergy Technology R&D Co., Ltd
* @Filename : myg0025_opamp.c
* @brief    : API file of OPAMP module
* @Author   : AE Team
* @Version  : V1.0.0/2023-04-08
  * @log  V1.0.0/2023-04-08 Initial release
 ********************************************************************/


/* Includes ------------------------------------------------------------------*/
#include "myg0025_opamp.h"
#include "myg0025_rcc.h"


/** @addtogroup myg0025_StdPeriph_Driver
  * @{
  */

/** @defgroup OPAMP OPAMP
  * @brief OPAMP modules
  * @{
  */

/** @defgroup OPAMP_Private_Functions OPAMP_Private_Functions
  * @{
  */

/**
  * @brief  Deinitializes the OPAMP peripheral registers to their default reset values.
  */
void OPAMP_DeInit(void)
{
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_OPAMP, ENABLE);
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_OPAMP, DISABLE);
}

/**
  * @brief  Initialize some features of OPAMP instance.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  OPAMP_InitStruct: Pointer to a OPAMP_InitTypeDef structure.
  * @retval An ErrorStatus enumeration value:
  *          - SUCCESS: OPAMP registers are initialized
  *          - ERROR: OPAMP registers are not initialized
  */
ErrorStatus OPAMP_Init(OPAMP_TypeDef *OPAMPx, OPAMP_InitTypeDef *OPAMP_InitStruct)
{
    ErrorStatus status = SUCCESS;

    if (OPAMP_IsLocked(OPAMPx) == 0U)
    {
        OPAMPx->CSR &= ~(OPAMP_CSR_CALON
                         |     OPAMP_CSR_VP_SEL
                         |     OPAMP_CSR_VM_SEL
                        );
        OPAMPx->CSR |= (OPAMP_InitStruct->FunctionalMode
                        |     OPAMP_InitStruct->InputNonInverting
                        |     OPAMP_InitStruct->InputInverting
                       );
    }
    else
    {
        /* Initialization error: OPAMP instance is locked. */
        status = ERROR;
    }

    return status;
}

/**
  * @brief  Set OPAMP instance operating mode.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  Mode: OPAMP_FUNCTIONAL_MODE,OPAMP_CALIBRATION_MODE.
  */
void OPAMP_SetMode(OPAMP_TypeDef *OPAMPx, uint32_t Mode)
{
    OPAMPx->CSR &= ~OPAMP_CSR_CALON;
    OPAMPx->CSR |= Mode;
}

/**
  * @brief  Get OPAMP mode calibration or functional.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP operating mode.
  */
uint32_t OPAMP_GetMode(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_CALON)) >> OPAMP_CSR_CALON_Pos;
}

/**
  * @brief  Set OPAMP PGA gain.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  PGAGain:
  *         OPAMP_PGA_GAIN_1.
  *         OPAMP_PGA_GAIN_2.
  *         OPAMP_PGA_GAIN_5.
  *         OPAMP_PGA_GAIN_8.
  *         OPAMP_PGA_GAIN_10.
  *         OPAMP_PGA_GAIN_14.
  *         OPAMP_PGA_GAIN_16.
  *         OPAMP_PGA_GAIN_20.
  *         OPAMP_PGA_GAIN_2_VM0_FILTER.
  *         OPAMP_PGA_GAIN_5_VM0_FILTER.
  *         OPAMP_PGA_GAIN_8_VM0_FILTER.
  *         OPAMP_PGA_GAIN_10_VM0_FILTER.
  *         OPAMP_PGA_GAIN_14_VM0_FILTER.
  *         OPAMP_PGA_GAIN_16_VM0_FILTER.
  *         OPAMP_PGA_GAIN_20_VM0_FILTER.
  */
void OPAMP_SetPGAGain(OPAMP_TypeDef *OPAMPx, uint32_t PGAGain)
{
    OPAMPx->CSR &= ~(OPAMP_CSR_PGA_GAIN_Mask);
    OPAMPx->CSR |= PGAGain;
}

/**
  * @brief  Get OPAMP PGA gain.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP PGA gain.
  */
uint32_t OPAMP_GetPGAGain(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_PGA_GAIN)) >> OPAMP_CSR_PGA_GAIN_Pos;
}

/**
  * @brief  Set OPAMP non-inverting input connection.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  InputNonInverting:
  *         OPAMP_INPUT_NONINVERT_VP0.
  *         OPAMP_INPUT_NONINVERT_VP1.
  *         OPAMP_INPUT_NONINVERT_VP2.
  *         OPAMP_INPUT_NONINVERT_VP3.
  */
void OPAMP_SetInputNonInverting(OPAMP_TypeDef *OPAMPx, uint32_t InputNonInverting)
{
    OPAMPx->CSR &= ~OPAMP_CSR_VP_SEL;
    OPAMPx->CSR |= InputNonInverting;
}

/**
  * @brief  Get OPAMP non-inverting input connection.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP non-inverting input connection.
  */
uint32_t OPAMP_GetInputNonInverting(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_VP_SEL)) >> OPAMP_CSR_VP_SEL_Pos;
}

/**
  * @brief  Set OPAMP inverting input.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  InputInverting:
  *         OPAMP_INPUT_INVERT_VM0.
  *         OPAMP_INPUT_INVERT_VM1.
  *         OPAMP_MODE_PGA.
  *         OPAMP_MODE_FOLLOWER.
  */
void OPAMP_SetInputInverting(OPAMP_TypeDef *OPAMPx, uint32_t InputInverting)
{
    OPAMPx->CSR &= ~OPAMP_CSR_VM_SEL;
    OPAMPx->CSR |= InputInverting;
}

/**
  * @brief  Get OPAMP inverting input.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP inverting input.
  */
uint32_t OPAMP_GetInputInverting(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_VM_SEL)) >> OPAMP_CSR_VM_SEL_Pos;
}

/**
  * @brief  Set OPAMP non-inverting input secondary connection.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  InputNonInverting This parameter can be one of the following values:
  *         OPAMP_INPUT_NONINVERT_VP0_SEC.
  *         OPAMP_INPUT_NONINVERT_VP1_SEC.
  *         OPAMP_INPUT_NONINVERT_VP2_SEC.
  *         OPAMP_INPUT_NONINVERT_VP3_SEC.
  */
void OPAMP_SetInputNonInvertingSecondary(OPAMP_TypeDef *OPAMPx, uint32_t InputNonInverting)
{
    OPAMPx->CSR &= ~OPAMP_CSR_VP_SEL;
    OPAMPx->CSR |= InputNonInverting;
}

/**
  * @brief  Get OPAMP non-inverting input secondary connection
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP non-inverting input secondary connection.
  */
uint32_t OPAMP_GetInputNonInvertingSecondary(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_VP_SEL)) >> OPAMP_CSR_VP_SEL_Pos;
}

/**
  * @brief  Set OPAMP inverting input secondary connection.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  InputInverting This parameter can be one of the following values:
  *         OPAMP_INPUT_INVERT_VM0_SEC.
  *         OPAMP_INPUT_INVERT_VM1_SEC.
  */
void OPAMP_SetInputInvertingSecondary(OPAMP_TypeDef *OPAMPx, uint32_t InputInverting)
{
    OPAMPx->CSR &= ~OPAMP_CSR_VM_SEL;
    OPAMPx->CSR |= InputInverting;
}

/**
  * @brief  Get OPAMP inverting input secondary connection.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP inverting input secondary connection.
  */
uint32_t OPAMP_GetInputInvertingSecondary(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_VM_SEL)) >> OPAMP_CSR_VM_SEL_Pos;
}

/**
  * @brief  Set OPAMP trimming mode.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  TrimmingMode This parameter can be one of the following values:
  *         OPAMP_TRIMMING_FACTORY.
  *         OPAMP_TRIMMING_USER.
  */
void OPAMP_SetTrimmingMode(OPAMP_TypeDef *OPAMPx, uint32_t TrimmingMode)
{
    OPAMPx->CSR &= ~OPAMP_CSR_USER_TRIM;
    OPAMPx->CSR |= TrimmingMode;
}

/**
  * @brief  Get OPAMP trimming mode.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP trimming mode.
  */
uint32_t OPAMP_GetTrimmingMode(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_USER_TRIM)) >> OPAMP_CSR_USER_TRIM_Pos;
}

/**
  * @brief  Set OPAMP offset to calibrate the selected transistors.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  TransistorsDiffPair This parameter can be one of the following values:
  *         OPAMP_TRIMMING_PMOS_VREF_4PC_VDDA.
  *         OPAMP_TRIMMING_PMOS_VREF_10PC_VDDA.
  *         OPAMP_TRIMMING_NMOS_VREF_50PC_VDDA.
  *         OPAMP_TRIMMING_NMOS_VREF_95PC_VDDA.
  */
void OPAMP_SetCalibrationSelection(OPAMP_TypeDef *OPAMPx, uint32_t TransistorsDiffPair)
{
    OPAMPx->CSR &= ~OPAMP_CSR_CALSEL;
    OPAMPx->CSR |= TransistorsDiffPair;
}

/**
  * @brief  Get OPAMP offset to calibrate the selected transistors.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP offset to calibrate the selected transistors.
  */
uint32_t OPAMP_GetCalibrationSelection(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_CALSEL)) >> OPAMP_CSR_CALSEL_Pos;
}

/**
  * @brief  Get OPAMP calibration result of toggling output.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP calibration result of toggling output.
  */
uint32_t OPAMP_GetCalibrationOutput(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_CALOUT)) >> OPAMP_CSR_CALOUT_Pos;
}

/**
  * @brief  Get OPAMP trimming factor for the selected transistors.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  TransistorsDiffPair This parameter can be one of the following values:
  *         OPAMP_TRIMMING_NMOS.
  *         OPAMP_TRIMMING_PMOS.
  * @retval OPAMP trimming factor for the selected transistors.
  */
uint32_t OPAMP_GetTrimmingValue(OPAMP_TypeDef *OPAMPx, uint32_t TransistorsDiffPair)
{
    if (TransistorsDiffPair == OPAMP_TRIMMING_NMOS)
        return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_TRIMVOSN) >> 24);
    else
        return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_TRIMVOSP) >> 19);
}

/**
  * @brief  Enable OPAMP instance.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  */
void OPAMP_Enable(OPAMP_TypeDef *OPAMPx)
{
    OPAMPx->CSR &= ~OPAMP_CSR_OPAMPEN;
    OPAMPx->CSR |= OPAMP_CSR_OPAMPEN;
}

/**
  * @brief  Disable OPAMP instance.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  */
void OPAMP_Disable(OPAMP_TypeDef *OPAMPx)
{
    OPAMPx->CSR &= ~OPAMP_CSR_OPAMPEN;
}

/**
  * @brief  Get OPAMP instance enable state.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP instance enable state.
  */
uint32_t OPAMP_IsEnabled(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_OPAMPEN)) >> OPAMP_CSR_OPAMPEN_Pos;
}

/**
  * @brief  Set OPAMP forces calibration state.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  ForceVPState:
  *         OPAMP_FORCE_VP_DISABLE.
  *         OPAMP_FORCE_VP_ENABLE.
  */
void OPAMP_SetForceVPState(OPAMP_TypeDef *OPAMPx, uint32_t ForceVPState)
{
    OPAMPx->CSR &= ~OPAMP_CSR_FORCE_VP;
    OPAMPx->CSR |= ForceVPState;
}

/**
  * @brief  Set OPAMP output switch.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  OpaOutput:
            OPAMP_OUT0.
            OPAMP_OUT1.
            OPAMP_OUT2.
            OPAMP_OUTALL.
  * @param  NewState: new state of the OPAMPx  output.
  *          This parameter can be: ENABLE or DISABLE.
  */
void OPAMP_SetOutput(OPAMP_TypeDef *OPAMPx, OPAMP_OUT_SEL_Type OpaOutput, FunctionalState NewState)
{
    if (NewState != ENABLE)
    {
        if ((OPAMPx == OPAMP1) || (OPAMPx == OPAMP2))
        {
            if (OpaOutput == OPAMP_OUT0)
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL0_Mask;
            else if (OpaOutput == OPAMP_OUT1)
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL1_Mask;
            else
            {
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL0_Mask;
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL1_Mask;
            }
        }
        if (OPAMPx == OPAMP3)
        {
            if (OpaOutput == OPAMP_OUT0)
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL0_Mask;
            else if (OpaOutput == OPAMP_OUT1)
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL1_Mask;
            else if (OpaOutput == OPAMP_OUT2)
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL2_Mask;
            else
            {
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL0_Mask;
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL1_Mask;
                OPAMPx->CSR &= ~OPAMP_CSR_OPAMPx_OUT_SEL2_Mask;
            }
        }

    }
    else
    {
        if ((OPAMPx == OPAMP1) || (OPAMPx == OPAMP2))
        {
            if (OpaOutput == OPAMP_OUT0)
                OPAMPx->CSR |= OPAMP_CSR_OPAMPx_OUT_SEL0;
            else if (OpaOutput == OPAMP_OUT1)
                OPAMPx->CSR |= OPAMP_CSR_OPAMPx_OUT_SEL1;
            else
            {
                OPAMPx->CSR |= OPAMP_CSR_OPAMPx_OUT_SEL0;
                OPAMPx->CSR |= OPAMP_CSR_OPAMPx_OUT_SEL1;
            }
        }
        if (OPAMPx == OPAMP3)
        {
            if (OpaOutput == OPAMP_OUT0)
                OPAMPx->CSR |=  OPAMP_CSR_OPAMPx_OUT_SEL0;
            else if (OpaOutput == OPAMP_OUT1)
                OPAMPx->CSR |=  OPAMP_CSR_OPAMPx_OUT_SEL1;
            else if (OpaOutput == OPAMP_OUT2)
                OPAMPx->CSR |= OPAMP_CSR_OPAMPx_OUT_SEL2;
            else
            {
                OPAMPx->CSR |= OPAMP_CSR_OPAMPx_OUT_SEL0;
                OPAMPx->CSR |= OPAMP_CSR_OPAMPx_OUT_SEL1;
                OPAMPx->CSR |= OPAMP_CSR_OPAMPx_OUT_SEL2;
            }
        }
    }

}


/**
  * @brief  SET OPAMP Hardware trimming enable.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  */
void OPAMP_SetHardwareTrim(OPAMP_TypeDef *OPAMPx)
{
    OPAMPx->CSR &= ~OPAMP_CSR_HWT_EN;
    OPAMPx->CSR |= OPAMP_CSR_HWT_EN;
}

/**
  * @brief  GET OPAMP Hardware trimming status.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  */
uint32_t OPAMP_GetHardwareTrim(OPAMP_TypeDef *OPAMPx)
{
    return ((uint32_t)((OPAMPx->CSR & OPAMP_CSR_HWT_EN)) >> OPAMP_CSR_HWT_EN_Pos);
}


/**
  * @brief  Get OPAMP forces calibration state.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP forces calibration state.
  */
uint32_t OPAMP_GetForceVPState(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_FORCE_VP)) >> OPAMP_CSR_FORCE_VP_Pos;
}

/**
  * @brief  Set OPAMP calibration mode enable state.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  CALONState:
  *         OPAMP_CALON_DISABLE.
  *         OPAMP_CALON_ENABLE.
  */
void OPAMP_SetCALONState(OPAMP_TypeDef *OPAMPx, uint32_t CALONState)
{
    OPAMPx->CSR &= ~OPAMP_CSR_CALON;
    OPAMPx->CSR |= CALONState;
}

/**
  * @brief  Get OPAMP calibration mode enable state.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP calibration mode enable state.
  */
uint32_t OPAMP_GetCALONState(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_CALON)) >> OPAMP_CSR_CALON_Pos;
}

/**
  * @brief  Set OPAMP user trimming enable state.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  UserTrimState:
  *         OPAMP_USER_TRIM_DISABLE.
  *         OPAMP_USER_TRIM_ENABLE.
  */
void OPAMP_SetUserTrimState(OPAMP_TypeDef *OPAMPx, uint32_t UserTrimState)
{
    OPAMPx->CSR &= ~OPAMP_CSR_USER_TRIM;
    OPAMPx->CSR |= UserTrimState;
}

/**
  * @brief  Get OPAMP user trimming enable state.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP user trimming enable state.
  */
uint32_t OPAMP_GetUserTrimState(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_USER_TRIM)) >> OPAMP_CSR_USER_TRIM_Pos;
}

/**
  * @brief  Set OPAMP trimoffsetN value.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  TRIMOFFSETValue: 0x00~0x1F.
  */
void OPAMP_SetTRIMOFFSETN(OPAMP_TypeDef *OPAMPx, uint32_t TRIMOFFSETValue)
{
    OPAMPx->CSR &= ~OPAMP_CSR_TRIMVOSN;
    OPAMPx->CSR |= TRIMOFFSETValue << OPAMP_CSR_TRIMVOSN_Pos;
}

/**
  * @brief  Get OPAMP trimoffsetN value.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP trimoffsetN value.
  */
uint32_t OPAMP_GetTRIMOFFSETN(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_TRIMVOSN)) >> OPAMP_CSR_TRIMVOSN_Pos;
}

/**
  * @brief  Set OPAMP trimoffsetP value.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @param  TRIMOFFSETValue: 0x00~0x1F.
  */
void OPAMP_SetTRIMOFFSETP(OPAMP_TypeDef *OPAMPx, uint32_t TRIMOFFSETValue)
{
    OPAMPx->CSR &= ~OPAMP_CSR_TRIMVOSP;
    OPAMPx->CSR |= TRIMOFFSETValue << OPAMP_CSR_TRIMVOSP_Pos;
}

/**
  * @brief  Get OPAMP trimoffsetP value.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  * @retval OPAMP trimoffsetP value.
  */
uint32_t OPAMP_GetTRIMOFFSETP(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_TRIMVOSP)) >> OPAMP_CSR_TRIMVOSP_Pos;
}

/**
  * @brief  Lock OPAMP instance.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  */
void OPAMP_Lock(OPAMP_TypeDef *OPAMPx)
{
    OPAMPx->CSR &= ~OPAMP_CSR_LOCK;
    OPAMPx->CSR |= OPAMP_CSR_LOCK;
}

/**
  * @brief  Get OPAMP lock state.
  * @param  OPAMPx: OPAMP1,OPAMP2,OPAMP3.
  *@return
        * @retval OPAMP lock state.
  */
uint32_t OPAMP_IsLocked(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_LOCK)) >> OPAMP_CSR_LOCK_Pos;
}

/**
  * @brief  Set apb clock division as hardware trimming clock for OPAMP1,OPAMP2,OPAMP3.
  */
void OPAMP_HWTrimClk(void)
{
    *(uint32_t *)(0x40015C10) = OPAMP_CLKDIV1024;
}


/**
  * @brief  feedback loop GND selection.
  * @param  OPAMPx: OPAMP1,OPAMP2.
  * @param  OPAMP_GndSel:
            OPAMP_Gnd_Internal,
            OPAMP_Gnd_External,
  */
void OPAMP_GND_Sel(OPAMP_TypeDef *OPAMPx, uint32_t OPAMP_GndSel)
{
    OPAMPx->CSR &= ~OPAMP_CSR_GND_SEL_Mask;
    OPAMPx->CSR |=  OPAMP_GndSel;
}

/**
  * @brief  Get OPAMP feedback loop GND selection.
  * @param  OPAMPx: OPAMP1,OPAMP2.
  * @retval OPAMP PGA_N.
  */
uint32_t OPAMP_GetPGAGND_Sel(OPAMP_TypeDef *OPAMPx)
{
    return (uint32_t)((OPAMPx->CSR & OPAMP_CSR_GND_SEL)) >> OPAMP_CSR_GND_SEL_Pos;
}
/**
  * @}
  */
/**
  * @}
  */
/**
  * @}
  */

